import '/Frame/Log4';
import cluster from 'cluster';
import os from 'node:os';
import Koa from 'koa';
import http from 'node:http';
import serve from 'koa-static';
import cors from '@koa/cors';
import koaBody from 'koa-body';
import BaseConfig from '/Config/Base';
import ErrorJson from '/Frame/Plugins/ErrorJson';
import routerBase, { initRoute } from '/Frame/RouteBase';
import CacheBase from '/Frame/CacheBase';
import FuncBase from '/Frame/FuncBase';
import viewBase from '/Frame/viewBase';
import cronBase from '/Frame/CronBase';
import Common from '/App/common';
import { initModel } from '/Frame/ModelBase';
import { webSocketMainInit, WebSocketUse } from '/Frame/WebSocketBase';


/**
 * 主进程和子进程的共同使用的连接
 */
// 初始化数据库连接池
initModel();
// 初始化全局缓存redis
CacheBase();
// 初始化全局函数
global.G = new Common;
// 判断主进程还是子进程
cluster.isPrimary ? Primary() : Run();

//主进程
function Primary() {
    //主进程 （应有的功能,定时任务、数据库、缓存）
    webSocketMainInit(cluster);// websocket服务(主进程通信初始化)
    cronBase();//定时任务、数据库、缓存） (这个交给主进程执行，多个子进程执行会出现混乱)



    // 创建多个工作进程
    const numCPUs = os.cpus().length; // 获取CPU核心数
    let count = numCPUs;
    if (BaseConfig.clusterCount > 0) count = BaseConfig.clusterCount > numCPUs ? numCPUs : BaseConfig.clusterCount;
    for (let i = 0; i < count; i++) cluster.fork();
    logger.info(`共启动 [主进程] 1个(监听重启工作进程的作用) | [工作进程] ${count}个`);

    // 监听工作进程的退出事件
    cluster.on('exit', (worker, code, signal) => {
        logger.error(`Worker ${worker.process.pid} died with code ${code} and signal ${signal}`);
        // 重新启动工作进程
        setTimeout(() => {
            cluster.fork();
        }, 10000); // 10秒后重启
    });
}

// 子进程
function Run() {
    // 创建koa实例
    const app = new Koa();
    // 开启代理（宝塔都是代理的）
    app.proxy = BaseConfig.proxy;
    // 配置跨域中间件
    app.use(cors({
        origin: function (ctx) {
            if (BaseConfig.corsRule === '*') return '*'; // 允许所有源
            if (Array.isArray(BaseConfig.corsRule)) {
                const isOk = BaseConfig.corsRule.find(host => {
                    const hostNoPort = host?.replace(/^(http(s)?:\/\/)?([^:]+).*$/, '$3');
                    const regHost = new RegExp(`^(http(s)?:\/\/)?${hostNoPort}(:\\d+)?$`);
                    if (typeof ctx.headers.host != 'string') return true;
                    return regHost.test(ctx.headers.host);
                });
                if (isOk) return isOk;
                return '127.0.0.1'; // 返回允许的源
            }
            return String(BaseConfig.corsRule);
        },
        exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
        maxAge: 5,
        credentials: true,
        allowMethods: ['GET', 'POST', 'DELETE', 'PUT'],
        allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
    }));
    // 错误信息json处理
    app.use(ErrorJson());
    // 配置 koa-body 中间件
    app.use(koaBody(BaseConfig.koaBody));
    // 配置模板引擎
    app.use(viewBase(app));
    // 封装函数
    app.use(FuncBase(app));
    // 指定静态文件目录
    app.use(serve(BaseConfig.staticDir, { maxage: BaseConfig.cacheMaxage }));
    // 初始化路由
    initRoute();
    // 路由注册
    app.use(routerBase.routes()).use(routerBase.allowedMethods());
    // 判断端口
    const port = process.env.NODE_ENV === 'development' ? BaseConfig.devPort : BaseConfig.port;
    //创建服务
    const server = http.createServer(app.callback());
    // 创建 WebSocket 服务
    app.use(WebSocketUse(server));
    // 启动 Koa 应用
    server.listen(port, () => {
        logger.info(`[${process.env.NODE_ENV === 'development' ? '开发环境' : '生产环境'}] PID: ${process.pid} 服务器启动 [本地] http://localhost:${port} [局域网] http://${G.getCurrentLanIP()}:${port}`);
    }).on('error', (err: any) => {
        logger.error(`[${process.env.NODE_ENV === 'development' ? '开发环境' : '生产环境'}] PID: ${process.pid} 服务器启动失败:`, err);
    });
}